package cn.minhx.mw.dtp.sdk.domain;

import cn.minhx.mw.dtp.sdk.domain.model.entity.ThreadPoolConfigEntity;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ThreadPoolExecutor;

import static com.alibaba.fastjson2.JSON.toJSONString;

/**
 * @author minhx
 */
@Slf4j
public class DynamicThreadPoolServiceImpl implements DynamicThreadPoolService {

    private final String applicationName;
    private final Map<String, ThreadPoolExecutor> executorMap;

    public DynamicThreadPoolServiceImpl(String applicationName, Map<String, ThreadPoolExecutor> executorMap) {
        this.applicationName = applicationName;
        this.executorMap = executorMap;
    }

    @Override
    public List<ThreadPoolConfigEntity> getThreadPoolConfigList() {
        List<ThreadPoolConfigEntity> configEntityList = new ArrayList<>(executorMap.size());
        executorMap.forEach((threadPoolName, executor) -> configEntityList.add(ThreadPoolConfigEntity.builder()
                .appName(applicationName)
                .threadPoolName(threadPoolName)
                .corePoolSize(executor.getCorePoolSize())
                .maximumPoolSize(executor.getMaximumPoolSize())
                .activeCount(executor.getActiveCount())
                .poolSize(executor.getPoolSize())
                .queueType(executor.getQueue().getClass().getSimpleName())
                .queueSize(executor.getQueue().size())
                .remainingCapacity(executor.getQueue().remainingCapacity())
                .build()));
        log.debug("[动态线程池-配置查询]线程池【appName={}】配置信息：{}", applicationName, toJSONString(configEntityList));
        return configEntityList;
    }

    @Override
    public ThreadPoolConfigEntity getThreadPoolConfigByName(String threadPoolName) {
        ThreadPoolExecutor executor = executorMap.get(threadPoolName);
        if (Objects.isNull(executor)) {
            log.debug("[动态线程池-配置查询]线程池【appName={} threadPoolName={}】不存在", applicationName, threadPoolName);
            return null;
        }
        ThreadPoolConfigEntity configEntity = ThreadPoolConfigEntity.builder()
                .appName(applicationName)
                .threadPoolName(threadPoolName)
                .corePoolSize(executor.getCorePoolSize())
                .maximumPoolSize(executor.getMaximumPoolSize())
                .activeCount(executor.getActiveCount())
                .poolSize(executor.getPoolSize())
                .queueType(executor.getQueue().getClass().getSimpleName())
                .queueSize(executor.getQueue().size())
                .remainingCapacity(executor.getQueue().remainingCapacity())
                .build();
        log.debug("[动态线程池-配置查询]线程池【appName={} threadPoolName={}】配置信息：{}", applicationName, threadPoolName, toJSONString(configEntity));
        return configEntity;
    }

    @Override
    public void updateThreadPoolConfig(ThreadPoolConfigEntity configEntity) {
        if (Objects.isNull(configEntity) || !Objects.equals(applicationName, configEntity.getAppName()) || !executorMap.containsKey(configEntity.getThreadPoolName())) {
            log.debug("[动态线程池-配置更新]未找到匹配的线程池。 appName={} configEntity={}", applicationName, toJSONString(configEntity));
            return;
        }
        ThreadPoolExecutor executor = executorMap.get(configEntity.getThreadPoolName());
        int corePoolSizeOld = executor.getCorePoolSize();
        int maximumPoolSizeOld = executor.getMaximumPoolSize();
        // 调整线程池配置 ⌈核心线程数 & 最大线程数⌋
        executor.setCorePoolSize(configEntity.getCorePoolSize());
        executor.setMaximumPoolSize(configEntity.getMaximumPoolSize());
        log.info("[动态线程池-配置更新]完成。 线程池【appName={} threadPoolName={}】核心线程数从{}调整为{}, 最大线程数从{}调整为{}, configEntity={}",
                applicationName, configEntity.getThreadPoolName(), corePoolSizeOld, configEntity.getCorePoolSize(), maximumPoolSizeOld, configEntity.getMaximumPoolSize(), toJSONString(configEntity));
    }
}
